﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.Diagnostics.CodeAnalysis;

namespace Steve
{
    public abstract class CategoryRepository : AuditRepositoryBase
    {
        const string CategoriesKey = "Categories";
        
        [Import]
        public ICacheService Cache { get; set; }
        [Import]
        public IConfiguration Config { get; set; }

        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
        protected abstract IEnumerable<Category> GetCategoriesCore();

        [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
        public IEnumerable<Category> GetCategories()
        {
            return Cache.GetValue<IEnumerable<Category>>(CacheType.Category, CategoriesKey, Config.DataCacheTtl, () => GetCategoriesCore());
        }

        public IEnumerable<Category> GetCategoriesByDescription(string toMatch)
        {
            return GetCategories().Where(c => c.CategoryDescription.IndexOf(toMatch, StringComparison.CurrentCultureIgnoreCase) >= 0).ToList();
        }

        public IEnumerable<Category> GetCategories(IEnumerable<string> names)
        {
            return (from c in GetCategories()
                    join n in names on c.CategoryName equals n
                    select c).ToList();
        }

        public Category SaveCategory(Category toSave)
        {
            if (toSave == null) throw new ArgumentNullException("toSave");

            ProcessAudit(toSave);
            var returnValue = SaveCategoryCore(toSave);

            Cache.Invalidate(CacheType.Category);
            return returnValue;
        }

        protected abstract Category SaveCategoryCore(Category toSave);

        public Category GetCategory(string categoryName)
        {
            return GetCategories().Where(c => string.Equals(c.CategoryName, categoryName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
        }
    }
}
